import logging
import datetime
from django.shortcuts import render
from django import http
from django.views import View
from django.core.paginator import Paginator, EmptyPage
from django.utils import timezone

from content.utils import get_categories
from goods.utils import get_breadcrumb
from goods.models import GoodsCategory, SKU, GoodsVisitCount
from meiduo_mall.utils.response_code import RETCODE
# Create your views here.

logger = logging.getLogger('django')


class DetailCountView(View):
    """统计商品访问量视图"""
    def post(self, request, category_id):
        # 判断该商品是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('该商品不存在')

        # 获取当天时间对象，方法一
        now = datetime.datetime.now()
        # 获取年月日拼接字符串
        date_str = '%d-%02d-%02d' % (now.year, now.month, now.day)
        # 将年月日字符串转datetime对象，用于存储数据库
        today_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')  # strftime是将时间对象转为时间字符串
        # 获取当天时间对象，方法二
        # t = timezone.localtime()  # 获取当前时间的时间对象
        # today_str = '%d-%02d-%02d' % (t.year, t.month, t.day)  # 将当前时间对象的年月日拼接成指定字符串
        # today_date = datetime.datetime.strptime(today_str, '%Y-%m-%d')  # 将拼接的字符串转为datetime对象用于数据库的存储

        # 在访问量表中查询该商品当天的浏览量记录
        try:
            # count_data = GoodsVisitCount.objects.get(date=today_date)
            count_data = category.goodsvisitcount_set.get(date=today_date)
        except GoodsVisitCount.DoesNotExist:
            count_data = GoodsVisitCount()

        try:
            count_data.category = category
            count_data.date = today_date
            count_data.count += 1
            count_data.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加记录失败'})

        # 返回结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


class DetailView(View):
    """商品详情页视图"""
    def get(self, request, sku_id):
        # 获取sku
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')
        # 获取商品分类
        categories = get_categories()
        # 获取面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 商品详情
        """
        1. 从当前sku获取spu
        2. 从spu获取规格列表
        3. 获取每个规格的可选值列表
        4. 获取该spu的所有sku
        5. 通过规格约束获取每个sku在该规格下的所有该规格的种类
        [
            sepc1: [
                {sku_id: sku_id, option: option},
                {sku_id: sku_id, option: option},
                ...
            ],
            spec2: {
                {sku_id: sku_id, option: option},
                {sku_id: sku_id, option: option},
                ...
            },
            ...
        ]
        [
            {
                feature: spec,
                option_list: [
                    {sku_id: sku_id, option: option},
                    {sku_id: sku_id, option: option},
                    ...
                ]
            },
            {},
            ...
        ]
        
        
        """
        # 创建商品规格数据
        """
        [
            {
                feature: spec_1,
                option_list: [
                    {sku_id: sku_id, value: option_value}
                ]
            },
            {},
            ...
        ]
        """
        # # 从当前sku获取spu
        # spu = sku.spu
        # # spu获取规格列表
        # spec_list = spu.specs.order_by('id')
        # # 获取该spu的所有sku
        # skus = spu.sku_set.all()
        # goods_specs = [
        #     {
        #         'feature': spec.name,
        #         'option_list': [
        #             {
        #                 'sku_id': sku.id,
        #                 'value': sku.specs.get(spec_id=spec.id).option.value
        #             }
        #             for sku in skus
        #         ]
        #     }
        #     for spec in spec_list
        # ]

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')  # [(spec_1, option_1), (spec_2, option_2), ...]
        sku_key = []  # [option_1_id, option_2_id, ...]
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 构造数据
        content = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }
        # 返回结果
        return render(request, 'detail.html', content)


class HotGoodsView(View):
    """热销商品视图"""
    def get(self, request, category_id):
        """
        返回数据格式
        {
            "code":"0",
            "errmsg":"OK",
            "hot_skus":[
                {
                    "id":6,
                    "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRbI2ARekNAAFZsBqChgk3141998",
                    "name":"Apple iPhone 8 Plus (A1864) 256GB 深空灰色 移动联通电信4G手机",
                    "price":"7988.00"
                },
                {
                    "id":14,
                    "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRdMSAaDUtAAVslh9vkK04466364",
                    "name":"华为 HUAWEI P10 Plus 6GB+128GB 玫瑰金 移动联通电信4G手机 双卡双待",
                    "price":"3788.00"
                }
            ]
        }
        """
        # # 判断是否存在该商品
        # try:
        #     category = GoodsCategory.objects.get(id=category_id)
        # except Exception as e:
        #     logger.error(e)
        #     return http.HttpResponseForbidden('不存在的商品')
        # # 获取该商品的skus，并按sales排序
        # try:
        #     skus = category.sku_set.filter(is_launched=True).order_by('-sales')[:2]
        # except Exception as e:
        #     logger.error(e)
        #     return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '数据库错误'})
        try:
            skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '数据库错误'})
        # 构造数据
        content = {
            'code': RETCODE.OK,
            'errmsg': 'OK',
            'hot_skus': [
                {
                    'id': sku.id,
                    # 只有django和Jinja2模板引擎可以用model.ImageField字段的url方法从而使用自定义的文件管理系统拼接图片路径，
                    # vue识别不了，如果要用vue渲染前端页面图片，必须先使用django调用文件管理系统拼接文件服务路径，然后赋值给vue
                    'default_image_url': sku.default_image.url,
                    'name': sku.name,
                    'price': sku.price
                }
                for sku in skus
            ]
        }
        # 返回响应
        return http.JsonResponse(content)


class ListView(View):
    def get(self, request, category_id, page_num):
        """获取商品列表页"""
        # 获取参数
        sort = request.GET.get('sort', 'default')

        # 校验参数
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('商品不存在')
        if sort.lower() == 'price':  # 按价格由低到高排序
            sort_field = 'price'
        elif sort.lower() == 'hot':  # 按销量由高到低排序
            sort_field = '-sales'
        else:  # 按上架日期由新到旧排序
            sort = 'default'
            sort_field = 'create_time'
        # 实现业务逻辑
        # 商品分类
        category_list = get_categories()
        # 面包屑导航
        breadcrumb = get_breadcrumb(category)
        # 分页
        # 查询商品
        # skus = SKU.objects.filter(category=category, is....
        # skus = SKU.objects.filter(category_id=category_id, is....
        # skus = SKU.objects.filter(category=category, is_launched=True).order_by(sort_field)
        # all_sku1 = SKU.objects.filter(category_id=category_id, is_launched=True).order_by(sort_field)
        all_sku = category.sku_set.filter(is_launched=True).order_by(sort_field)  # 有经验的写法
        paginator = Paginator(all_sku, 5)
        try:
            page_skus = paginator.page(page_num)  # 获取指定页数的数据
        except EmptyPage:
            return http.HttpResponseNotFound('Empty Page')
        total_page = paginator.num_pages  # 获取总页数

        context = {
            'categories': category_list,
            'breadcrumb': breadcrumb,
            'sort': sort,  # 排序字段
            'category': category,  # 第三级分类
            'page_skus': page_skus,  # 分页后数据
            'total_page': total_page,  # 总页数
            'page_num': page_num,  # 当前页码
        }

        return render(request, 'list.html', context=context)

